package com.plian.system.service.fr.monthindicators.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.TokenUtil;
import com.plian.Tools.UuidUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.config.exception.MyRuntimeException;
import com.plian.system.constant.sys.FormTypeConstant;
import com.plian.system.dao.fr.financeindicators.FinanceIndicatorsDao;
import com.plian.system.dao.fr.fstdvalue.FstdvalueDao;
import com.plian.system.dao.fr.indicatorsstdvalue.IndicatorsStdvalueDao;
import com.plian.system.dao.fr.monthindicators.MonthIndicatorsDao;
import com.plian.system.dao.fr.monthindicatorsvalue.MonthIndicatorsValueDao;
import com.plian.system.dao.sys.orgzation.OrgzationDao;
import com.plian.system.entity.fr.bulletin.BulletinValue;
import com.plian.system.entity.fr.bulletin.NewBulletin;
import com.plian.system.entity.fr.indicators.MonthIndicators;
import com.plian.system.mapper.fr.indicators.MonthIndicatorsMapper;
import com.plian.system.model.CommonCode;
import com.plian.system.model.ListResult;
import com.plian.system.model.ObjResult;
import com.plian.system.model.page.Page;
import com.plian.system.mybatis.base.BaseFlowService;
import com.plian.system.service.fr.bulletin.INewBulletinService;
import com.plian.system.service.fr.monthindicators.IMonthIndicatorsService;
import com.plian.system.service.sys.code.IFormCodeService;
import com.plian.system.service.sys.file.FileService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.sys.user.ISysUserService;
import com.plian.system.service.wf.FormWorkflowService;
import com.plian.system.service.yth.IMonthlyDebtService;
import com.plian.system.vo.fr.bulletin.NewBulletinVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

import static com.plian.system.constant.sys.FormStatusConstant.*;
import static com.plian.system.constant.sys.FormTypeConstant.FR_MONTHINDICATORS;

/**
 * 说明：企业月度指标录入
 */
@Service
@Transactional
@Slf4j
public class MonthIndicatorsServiceImpl extends ServiceImpl<MonthIndicatorsMapper, MonthIndicators> implements IMonthIndicatorsService, BaseFlowService {

    @Autowired
    MonthIndicatorsDao monthindicatorsDao;
    @Autowired
    MonthIndicatorsValueDao monthindicatorsvalueDao;
    @Autowired
    FileService fileService;
    @Autowired
    FormWorkflowService formWorkflowService;
    @Autowired
    FinanceIndicatorsDao financeindicatorsDao;
    @Autowired
    IndicatorsStdvalueDao indicatorsstdvalueDao;
    @Autowired
    FstdvalueDao fstdvalueDao;
    @Autowired
    IFormCodeService formCodeService;
    @Autowired
    private INewBulletinService newBulletinService;

    @Autowired
    private IMonthlyDebtService monthlyDebtService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IOrgService orgService;

    @Autowired
    private OrgzationDao orgzationDao;
    private static final Logger LOGGER = LoggerFactory.getLogger(MonthIndicatorsServiceImpl.class);

    /**
     * 保存
     *
     * @param pd
     * @return
     */
    public ObjResult save(PageData pd) {
        try {
            String id = UuidUtil.get32UUID();
            if (pd.getInteger("fmonth") < 10) {
                pd.put("fmonth", "0" + pd.getInteger("fmonth"));
            }
            pd.put("id", id);
            pd.put("code", formCodeService.getCode(FormTypeConstant.FR_MONTHINDICATORS));
            pd.put("status", "0");
            pd.put("createTime", new Date());
            pd.put("updateTime", new Date());
            pd.put("createUser", TokenUtil.getTokenUserId());
            pd.put("updateUser", TokenUtil.getTokenUserId());
            pd.put("formType", FormTypeConstant.FR_MONTHINDICATORS);
            monthindicatorsDao.save(pd);
//    ObjectMapper mapper = new ObjectMapper();
//        //保存从表: 月度指标从表
//        List<PageData> list_MonthIndicatorsValue = mapper.convertValue((List<PageData>) pd.get("listMonthIndicatorsValue"), new TypeReference<List<PageData>>() {});
//        saveMonthIndicatorsValue(list_MonthIndicatorsValue,id);
            //保存附件
            fileService.saveAll(id, (List<HashMap>) pd.get("list_doc"));
            HashMap<String, Object> processVariable = new HashMap<>();
            formWorkflowService.startProcessAndSimulate(id, pd.getString("formType"), processVariable);
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 修改
     *
     * @param pd
     * @return
     */
    public ObjResult edit(PageData pd) {
        try {
            String id = pd.getString("id");
            if (pd.getInteger("fmonth") < 10) {
                pd.put("fmonth", "0" + pd.getInteger("fmonth"));
            }
            pd.put("updateTime", new Date());
            pd.put("updateUser", TokenUtil.getTokenUserId());
            monthindicatorsDao.edit(pd);
//        ObjectMapper mapper = new ObjectMapper();
//            //修改从表: 月度指标从表
//            List<PageData> list_MonthIndicatorsValue = mapper.convertValue((List<PageData>) pd.get("listMonthIndicatorsValue"), new TypeReference<List<PageData>>() {});
//            monthindicatorsvalueDao.delPrenteId(id);
//            saveMonthIndicatorsValue(list_MonthIndicatorsValue,id);
            //修改附件
            fileService.edit(id, (List<HashMap>) pd.get("list_doc"));
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 查询列表
     *
     * @return
     */
    public ListResult listPage(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            boolean isPage = true;
            if (pd.containsKey("isPage")) {
                isPage = (boolean) pd.get("isPage");
            }
            Page page = new Page(isPage, pd);
            List<PageData> list = monthindicatorsDao.listPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 查询列表
     *
     * @return
     */
    public ListResult listReport(PageData pd) {
        ListResult listResult;
        try {
            pd.put("orgId", TokenUtil.getTokenOrgId());
            boolean isPage = true;
            if (pd.containsKey("isPage")) {
                isPage = (boolean) pd.get("isPage");
            }
            pd.put("status", FINISH);
            Page page = new Page(isPage, pd);
            List<PageData> list = monthindicatorsDao.listPage(page);
            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(list);
            listResult.setTotal(page.getTotal());
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
        }
        return listResult;
    }

    /**
     * 根据id查询
     *
     * @param pd
     * @return
     */
    public ObjResult findbyid(PageData pd) {
        ObjResult objResult;
        String id = pd.getString("id");
        try {
            PageData p = monthindicatorsDao.findbyid(id);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p);
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
            return objResult;
        }
    }

    /**
     * 根据id查询
     *
     * @param pd
     * @return
     */
    public ListResult findbyorg(PageData pd) {
        ListResult listResult;
        try {
            PageData org = orgzationDao.findbyid(pd.getString("orgId"));
            PageData p = new PageData();
            String[] fieldName = {"SUM_ZCZE", "SUM_FZZE", "SUM_LDFZ", "SUM_DXFZZE", "SUM_LXZC", "SUM_LRZE", "SUM_ZBHLXZC", "SUM_JYHDCSDXJLLJE"};
            String[] names = {"资产负债率", "已获利息倍数", "带息负债比率", "现金流动负债比率", "本期账面资产总额", "本期账面负债总额"};
            p.put("fieldName", fieldName);
            p.put("month", pd.getString("fmonth"));
            p.put("years", new String[]{pd.getString("fyear")});
            p.put("orgId", pd.getString("orgId"));
            BigDecimal ZCZE = new BigDecimal(0);
            BigDecimal FZZE = new BigDecimal(0);
            BigDecimal LDFZ = new BigDecimal(0);
            BigDecimal DXFZZE = new BigDecimal(0);
            BigDecimal LXZC = new BigDecimal(0);
            BigDecimal LRZE = new BigDecimal(0);
            BigDecimal ZBHLXZC = new BigDecimal(0);
            BigDecimal JYHDCSDXJLLJE = new BigDecimal(0);

            BigDecimal Group_ZCZE = new BigDecimal(0);
            BigDecimal Group_FZZE = new BigDecimal(0);
            BigDecimal Group_LDFZ = new BigDecimal(0);
            BigDecimal Group_DXFZZE = new BigDecimal(0);
            BigDecimal Group_LXZC = new BigDecimal(0);
            BigDecimal Group_LRZE = new BigDecimal(0);
            BigDecimal Group_ZBHLXZC = new BigDecimal(0);
            BigDecimal Group_JYHDCSDXJLLJE = new BigDecimal(0);


            BigDecimal G1 = new BigDecimal("0");
            BigDecimal G2 = new BigDecimal("0");
            BigDecimal G3 = new BigDecimal("0");
            BigDecimal G4 = new BigDecimal("0");
            List<PageData> resultList = new ArrayList<>();
            NewBulletinVO queryParam = new NewBulletinVO();
            queryParam.setYear(pd.getString("fyear"));
            queryParam.setMonth(pd.getString("fmonth"));
            queryParam.setOrgId(pd.getString("orgId"));
            NewBulletin singleBulletin = newBulletinService.getSingleOneByParam(queryParam);
            if (singleBulletin != null && CollectionUtil.isNotEmpty(singleBulletin.getBulletinValues())) {
                List<BulletinValue> values = singleBulletin.getBulletinValues();


                for (BulletinValue value : values) {
                    if ("ZCZE".equals(value.getColumnName())) {
                        ZCZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("FZZE".equals(value.getColumnName())) {
                        FZZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("LDFZ".equals(value.getColumnName())) {
                        LDFZ = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("DXFZZE".equals(value.getColumnName())) {
                        DXFZZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("LXZC".equals(value.getColumnName())) {
                        LXZC = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("LRZE".equals(value.getColumnName())) {
                        LRZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("ZBHLXZC".equals(value.getColumnName())) {
                        ZBHLXZC = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }

                    if ("JYHDCSDXJLLJE".equals(value.getColumnName())) {
                        JYHDCSDXJLLJE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                    }
                }
            }

            int i = 0;
            for (String s : names) {
                PageData result = new PageData();
                result.put("code", "G" + (i + 1));
                result.put("name", s);
                result.put("isGroup", "0");
                switch (i) {
                    case 0:
                        if (ZCZE.compareTo(new BigDecimal("0")) != 0) {
                            G1 = FZZE.divide(ZCZE, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                        }
                        result.put("actualValue", G1);
                        break;
                    case 1:
                        ZBHLXZC = ZBHLXZC.add(LXZC);
                        if (ZBHLXZC.compareTo(new BigDecimal("0")) != 0) {
                            G2 = LXZC.add(LRZE).divide(ZBHLXZC, 2, BigDecimal.ROUND_HALF_UP);
                        }
                        result.put("actualValue", G2);
                        break;
                    case 2:
                        if (FZZE.compareTo(new BigDecimal("0")) != 0) {
                            G3 = DXFZZE.divide(FZZE, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                        }
                        result.put("actualValue", G3);
                        break;
                    case 3:
                        if (LDFZ.compareTo(new BigDecimal("0")) != 0) {
                            G4 = JYHDCSDXJLLJE.divide(LDFZ, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                        }
                        result.put("actualValue", G4);
                        break;
                    case 4:
                        result.put("actualValue", ZCZE);
                        break;
                    case 5:
                        result.put("actualValue", FZZE);
                        break;
                    default:
                        break;
                }
                resultList.add(result);
                i++;
            }

            if ("0".equals(org.getString("typeCode")) || "3".equals(org.getString("typeCode"))) {
                NewBulletin groupBulletin = newBulletinService.getGroupOneByParam(queryParam);
                if (groupBulletin != null && CollectionUtil.isNotEmpty(groupBulletin.getBulletinValues())) {
                    List<BulletinValue> values = groupBulletin.getBulletinValues();
                    for (BulletinValue value : values) {
                        if ("ZCZE".equals(value.getColumnName())) {
                            Group_ZCZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("FZZE".equals(value.getColumnName())) {
                            Group_FZZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("LDFZ".equals(value.getColumnName())) {
                            Group_LDFZ = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("DXFZZE".equals(value.getColumnName())) {
                            Group_DXFZZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("LXZC".equals(value.getColumnName())) {
                            Group_LXZC = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("LRZE".equals(value.getColumnName())) {
                            Group_LRZE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("ZBHLXZC".equals(value.getColumnName())) {
                            Group_ZBHLXZC = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }

                        if ("JYHDCSDXJLLJE".equals(value.getColumnName())) {
                            Group_JYHDCSDXJLLJE = value.getYearAmount() != null ? value.getYearAmount() : new BigDecimal(0);
                        }
                    }
                }

                i = 0;
                for (String s : names) {
                    PageData result = new PageData();
                    result.put("code", "G" + (i + 1));
                    result.put("name", s);
                    result.put("isGroup", "1");
                    switch (i) {
                        case 0:
                            if (Group_ZCZE.compareTo(new BigDecimal("0")) != 0) {
                                G1 = Group_FZZE.divide(Group_ZCZE, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                            }
                            result.put("actualValue", G1);
                            break;
                        case 1:
                            Group_ZBHLXZC = Group_ZBHLXZC.add(Group_LXZC);
                            if (Group_ZBHLXZC.compareTo(new BigDecimal("0")) != 0) {
                                G2 = Group_LXZC.add(Group_LRZE).divide(Group_ZBHLXZC, 2, BigDecimal.ROUND_HALF_UP);
                            }
                            result.put("actualValue", G2);
                            break;
                        case 2:
                            if (Group_FZZE.compareTo(new BigDecimal("0")) != 0) {
                                G3 = Group_DXFZZE.divide(Group_FZZE, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                            }
                            result.put("actualValue", G3);
                            break;
                        case 3:
                            if (Group_LDFZ.compareTo(new BigDecimal("0")) != 0) {
                                G4 = Group_JYHDCSDXJLLJE.divide(Group_LDFZ, 4, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100"));
                            }
                            result.put("actualValue", G4);
                            break;
                        case 4:
                            result.put("actualValue", Group_ZCZE);
                            break;
                        case 5:
                            result.put("actualValue", Group_FZZE);
                            break;
                        default:
                            break;
                    }
                    resultList.add(result);
                    i++;
                }
            }

            listResult = new ListResult(CommonCode.SUCCESS);
            listResult.setList(resultList);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            listResult = new ListResult(CommonCode.ERROR);
            return listResult;
        }
        return listResult;
    }

    public ObjResult del_ids(List<String> ids) {
        try {
            ObjResult objResult = new ObjResult(CommonCode.SUCCESS);
            monthindicatorsDao.del_ids(ids);
            for (String s : ids) {
                formWorkflowService.deleteProcessInstance(s);
            }
            return objResult;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            return new ObjResult(CommonCode.ERROR);
        }
    }

    /**
     * 保存
     *
     * @param list    从表列表
     * @param prentId 主键id
     */
    private void saveMonthIndicatorsValue(List<PageData> list, String prentId) throws Exception {
        if (list != null && list.size() > 0) {
            for (PageData pageData : list) {
                pageData.put("monthIndicatorsId", prentId);
                pageData.put("id", UuidUtil.get32UUID());
            }
            monthindicatorsvalueDao.saveAll(list);
        }
    }

    /**
     * 查询主表，从表数据
     *
     * @param pd
     * @return
     */
    public ObjResult findidAll(PageData pd) {
        String id = pd.getString("id");
        ObjResult objResult;
        try {
            //主表信息
            PageData p = monthindicatorsDao.findbyid(id);
            List<PageData> list_MonthIndicatorsValue = monthindicatorsvalueDao.find_parentId(id);
            p.put("listMonthIndicatorsValue", list_MonthIndicatorsValue);
            objResult = new ObjResult(CommonCode.SUCCESS);
            objResult.setPageData(p);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            objResult = new ObjResult(CommonCode.ERROR);
        }
        return objResult;
    }

    /**
     * 提交单据
     *
     * @param formId 单据id
     */
    public HashMap<String, Object> commit(String formId){
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(FLOW));
        ArrayList<String> ids = new ArrayList<>();
        ids.add(formId);
        pageData.put("id", ids);
        try {
            monthindicatorsDao.refer(pageData);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("上报失败");
        }
        //将需要提交的流程变量返回，用于工作流侧
        return new HashMap<String, Object>();
    }

    /**
     * 退回单据
     *
     * @param formId 单据id
     */
    public Boolean reject(String formId, int formState, String comment) {
        PageData pageData = new PageData();
        pageData.put("status", String.valueOf(formState));
        pageData.put("id", Collections.singletonList(formId));
        try {
            monthindicatorsDao.refer(pageData);
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException("回退失败");
        }
        return true;
    }

    /**
     * 单据完成后
     *
     * @param formId
     */
    public Boolean finish(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(FINISH));
            pageData.put("id", Collections.singletonList(formId));
            monthindicatorsDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("单据流转完成时修改单据状态失败！"));
        }
        return true;
    }

    /**
     * @param formIds 单据ids
     */
    public List<PageData> findByIds(List<String> formIds) {
        try {
            PageData pageData = new PageData();
            pageData.put("ids", formIds);
            List<PageData> byIds = monthindicatorsDao.findByIds(pageData);
            List<PageData> pageData1 = new ArrayList<>();
            for (PageData pd : byIds) {
                String unitname = pd.getString("UNITNAME");
                pd.put("orgName", unitname);
                pageData1.add(pd);
            }
            //UNITNAME
            return pageData1;
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
            throw new MyRuntimeException(new ObjResult("根据单据id列表查询报表失败！"));
        }
    }

    @Override
    public List<Integer> getFormType() {
        return Arrays.asList(FR_MONTHINDICATORS);
    }

    public void goBackToStash(String formId) {
        try {
            PageData pageData = new PageData();
            pageData.put("status", String.valueOf(UNREVIEWED));
            pageData.put("id", Collections.singletonList(formId));
            monthindicatorsDao.refer(pageData);
        } catch (Exception e) {
            LOGGER.error(ExceptionUtils.getStackTrace(e));
        }
    }
}
